<template>
  <div class="page">
    <!-- 全屏固定背景图（覆盖整个可视区域） -->
    <div class="page-bg" :style="pageBgStyle"></div>
    <BrandHeader />

    <!-- 顶部返回行（与播放器页一致的排布） -->
    <div class="page-topbar">
      <button class="back-btn" @click="goBack" aria-label="返回上一页">返回</button>
    </div>

    <!-- 顶部横幅：背景图 + 电影信息 -->
    <section v-if="detail" class="hero">
      <div class="hero-content">
        <div class="poster" :style="posterStyle"></div>
        <div class="info">
          <div class="title-line">
            <h1 class="title">{{ detail.title || '未命名电影' }}</h1>
            <span class="year" v-if="detail.year">{{ detail.year }}</span>
            <span class="avg-chip" :title="`共 ${avg.count} 条评分`">{{ ratingLabel }}</span>
          </div>
          <div class="genres" v-if="genresArr.length">
            <span class="g-tag" v-for="g in genresArr" :key="g">{{ g }}</span>
          </div>
          <div class="meta-grid">
            <div class="meta-row" v-if="detail.original_title">
              <span class="label">原名</span>
              <span class="value">{{ detail.original_title }}</span>
            </div>
            <div class="meta-row" v-if="detail.original_language">
              <span class="label">语言</span>
              <span class="value">{{ detail.original_language }}</span>
            </div>
            <div class="meta-row" v-if="detail.runtime">
              <span class="label">片长</span>
              <span class="value">{{ formatRuntime(detail.runtime) }}</span>
            </div>
            <div class="meta-row" v-if="detail.status">
              <span class="label">状态</span>
              <span class="value">{{ detail.status }}</span>
            </div>
            <div class="meta-row" v-if="isFiniteNum(detail.budget)">
              <span class="label">预算</span>
              <span class="value">${{ formatNumber(detail.budget) }}</span>
            </div>
            <div class="meta-row" v-if="isFiniteNum(detail.revenue)">
              <span class="label">票房</span>
              <span class="value">${{ formatNumber(detail.revenue) }}</span>
            </div>
            <div class="meta-row" v-if="isFiniteNum(detail.vote_average) || isFiniteNum(detail.vote_count)">
              <span class="label">TMDB</span>
              <span class="value">{{ formatTmdbScore(detail.vote_average, detail.vote_count) }}</span>
            </div>
            <!-- 单独一行的官网 -->
            <div class="meta-row full" v-if="detail.homepage">
              <span class="label">官网</span>
              <a class="value link" :href="detail.homepage" target="_blank" rel="noopener">{{ detail.homepage }}</a>
            </div>
            <!-- 单独一行的标语，放在官网下面 -->
            <div class="meta-row full" v-if="detail.tagline">
              <span class="label">标语</span>
              <span class="value">{{ detail.tagline }}</span>
            </div>
          </div>
          <p class="overview" v-if="detail.overview">{{ detail.overview }}</p>
          <div class="actions">
            <button class="btn btn-primary" @click="goPlay()">▶ 立即播放</button>
            <button class="btn" @click="addToWatchlist()">{{ addBtnLabel }}</button>
            <div class="btn rating-stars-btn" aria-label="点击星星评分">
              <span v-for="n in 5" :key="n" class="star2" aria-hidden="true"
                @mousemove="onStarMove($event, n)"
                @mouseleave="hoverRating = null"
                @click="onStarClick($event, n)"
              >
                <span class="star2-bg">★</span>
                <span class="star2-fill" :style="{ width: starFillPercent(hoverRating != null ? hoverRating : (myRating || 0), n) }">★</span>
              </span>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- 评分列表与统计 -->
    <section class="ratings-section">
      <div class="section-header">
        <h2 class="section-title">其他用户评分</h2>
        <div class="section-meta">{{ sectionMetaText }}</div>
      </div>

      <div v-if="ratings.items.length" class="rating-list">
        <div class="rating-item" v-for="(r, idx) in ratings.items" :key="idx">
          <div class="avatar">{{ r.username?.[0]?.toUpperCase() || '匿' }}</div>
          <div class="ri-right">
            <div class="ri-head">
              <span class="name">{{ r.username || '匿名用户' }}</span>
              <span class="stars" :aria-label="`评分 ${Number(r.score).toFixed(1)} / 5`">
                <span v-for="n in 5" :key="n" class="star2" aria-hidden="true">
                  <span class="star2-bg">★</span>
                  <span class="star2-fill" :style="{ width: starFillPercent(r.score, n) }">★</span>
                </span>
              </span>
              <span class="score">{{ Number(r.score).toFixed(1) }}</span>
            </div>
          </div>
        </div>
      </div>
      <div v-else class="empty">暂时没有评分，快来成为第一个打分的人吧～</div>
    </section>

    <!-- 评分弹窗 -->
  <RatingDialog :show="showRate" :movieTitle="detail?.title" :initialScore="myRating || 0" @submit="submitRating" @close="showRate=false" />

    <!-- 加入片单提示弹窗 -->
    <InfoDialog
      :show="showJoinDialog"
      title="加入片单"
      :message="joinDialogMessage"
      primaryText="确定"
      @close="showJoinDialog=false"
      @primary="showJoinDialog=false"
    />
  </div>
  
</template>

<script setup>
import { computed, onMounted, ref, watch, onBeforeUnmount } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { getMovieDetail, getMovieRatings, rateMovie } from '@/services/api'
import { watchlistService } from '@/services/watchlist.js'
import BrandHeader from '@/components/BrandHeader.vue'
import RatingDialog from '@/components/RatingDialog.vue'
import InfoDialog from '@/components/InfoDialog.vue'

// 当前用户ID（用于过滤评分列表）——正确解析 JWT 的 user_id
function parseJwtUserId(t) {
  try {
    const part = String(t || '').split('.')[1]
    if (!part) return null
    const base64 = part.replace(/-/g, '+').replace(/_/g, '/')
    const json = decodeURIComponent(atob(base64).split('').map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)).join(''))
    const payload = JSON.parse(json)
    // 后端使用 user_id；兼容历史 userId
    return payload?.user_id ?? payload?.userId ?? null
  } catch (_) {
    return null
  }
}
const currentUserId = (() => {
  const token = (typeof window !== 'undefined') ? localStorage.getItem('token') : null
  const uid = token ? parseJwtUserId(token) : null
  return uid != null ? String(uid) : ''
})()

const route = useRoute()
const router = useRouter()
const movieId = computed(() => Number(route.params.id))

const detail = ref(null)
const ratings = ref({ items: [] })
const avg = ref({ average: 0, count: 0 })
const myRating = ref(null) // 当前登录用户对本片的评分（1~5），null 表示未评分
const showRate = ref(false)
const showJoinDialog = ref(false)
const joinDialogMessage = ref('')
const inWatchlist = ref(false)
const addBtnLabel = computed(() => inWatchlist.value ? '已加入' : '+ 加入片单')

const genresArr = computed(() => {
  if (!detail.value?.genres) return []
  if (Array.isArray(detail.value.genres)) return detail.value.genres
  return String(detail.value.genres).split('|').filter(Boolean).slice(0, 6)
})

const posterStyle = computed(() => {
  const url = detail.value?.poster
  return url ? { backgroundImage: `url(${url})` } : {}
})

// 工具函数
const hoverRating = ref(null)
function onStarClick(e, n) {
  const rect = e.target.getBoundingClientRect()
  const x = e.clientX - rect.left
  const percent = x / rect.width
  const score = percent < 0.5 ? n - 0.5 : n
  submitRating(score)
  hoverRating.value = null
}
function onStarMove(e, n) {
  const rect = e.target.getBoundingClientRect()
  const x = e.clientX - rect.left
  const percent = x / rect.width
  hoverRating.value = percent < 0.5 ? n - 0.5 : n
}
function isFiniteNum(v) { const n = Number(v); return Number.isFinite(n) && !Number.isNaN(n) }
function formatRuntime(v) { const n = Number(v)||0; const h = Math.floor(n/60); const m = n%60; return h>0 ? `${h}小时${m}分` : `${n}分钟` }
function formatNumber(v) { try { return Number(v).toLocaleString('en-US') } catch(e) { return v } }
function formatTmdbScore(avg, cnt) { const a = Number(avg)||0; const c = Number(cnt)||0; return `${a.toFixed(1)} / 10 · ${c.toLocaleString('en-US')} 票` }

// 全屏背景样式（覆盖全页，内容层覆盖其上）
const pageBgStyle = computed(() => {
  const url = detail.value?.backdrop || detail.value?.poster
  // 更通透的纵向渐变，顶部稍深，向下逐渐变浅，保证文字可读性
  const gradient = 'linear-gradient(180deg, rgba(15,15,15,0.55) 0%, rgba(15,15,15,0.30) 40%, rgba(15,15,15,0.12) 80%, rgba(15,15,15,0.25) 100%)'
  return url ? { backgroundImage: `${gradient}, url(${url})` } : { background: '#0f0f0f' }
})

// 平均分展示为一位小数（他人评分 0-5）
const avgAverage = computed(() => {
  const a = Number(avg.value?.average || 0)
  return a.toFixed(1)
})

// 是否有他人评分
const hasLocalRatings = computed(() => Number(avg.value?.count || 0) > 0)

// 顶部评分徽标文本：优先显示 TMDB 评分，其次显示全体用户评分
const ratingLabel = computed(() => {
  // 优先显示 TMDB 评分
  if (isFiniteNum(detail.value?.vote_average) && isFiniteNum(detail.value?.vote_count)) {
    return `⭐ ${Number(detail.value.vote_average).toFixed(1)} / 10 · ${Number(detail.value.vote_count).toLocaleString()} 票 (TMDB)`
  }
  // 其次显示全体用户评分
  if (hasLocalRatings.value) {
    const cnt = Number(avg.value?.count || 0)
    return `⭐ ${avgAverage.value} / 5 · ${cnt} 人`
  }
  return '⭐ 暂无评分'
})

// 评分区段统计文本：优先显示 TMDB 评分，其次显示全体用户评分
const sectionMetaText = computed(() => {
  if (isFiniteNum(detail.value?.vote_average) && isFiniteNum(detail.value?.vote_count)) {
    return `TMDB评分 ${Number(detail.value.vote_average).toFixed(1)} / 10 · ${Number(detail.value.vote_count).toLocaleString()} 票`
  }
  if (hasLocalRatings.value) {
    const cnt = Number(avg.value?.count || 0)
    return `平均分 ${avgAverage.value} / 5 · 共 ${cnt} 条`
  }
  return '暂无评分'
})

function pickRandom(arr, n) {
  if (!Array.isArray(arr)) return []
  const copy = arr.slice()
  // 洗牌算法后切片，保证不重复
  for (let i = copy.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1))
    ;[copy[i], copy[j]] = [copy[j], copy[i]]
  }
  return copy.slice(0, Math.max(0, Math.min(n, copy.length)))
}

async function load() {
  if (!movieId.value) return
  myRating.value = null
  getMovieDetail(movieId.value).then(res => { detail.value = res.data || null }).catch(() => { detail.value = null })
  await refreshRatings()
}

function goPlay() {
  const token = localStorage.getItem('token')
  if (!token) {
    router.push({ path: '/login', query: { redirect: `/player/${movieId.value}` } })
    return
  }
  router.push({ name: 'player', params: { id: movieId.value } })
}

function goBack() {
  // 优先返回上一页，否则回到推荐页
  if (window.history.length > 1) router.back()
  else router.push('/recommend')
}

function openRating() {
  const token = localStorage.getItem('token')
  if (!token) {
    // 未登录先去登录
    router.push({ path: '/login', query: { redirect: router.currentRoute.value.fullPath } })
    return
  }
  showRate.value = true
}

function addToWatchlist() {
  const token = localStorage.getItem('token')
  if (!token) {
    // 与首页行为一致：未登录先去登录，再回到详情页
    router.push({ path: '/login', query: { redirect: router.currentRoute.value.fullPath } })
    return
  }
  const m = detail.value
  if (!m) return
  const id = m.id ?? m.movieId
  const existed = id != null ? watchlistService.has(id) : false
  const res = watchlistService.add(m)
  const title = m.title || '该影片'
  if (res && res.ok) {
    joinDialogMessage.value = `“${title}” ${existed ? '已在片单（已更新）' : '已加入片单'}`
    showJoinDialog.value = true
    inWatchlist.value = true
  } else {
    joinDialogMessage.value = `加入片单失败：${title}`
    showJoinDialog.value = true
  }
}

async function submitRating(score) {
  try {
    const token = localStorage.getItem('token')
    if (!token) { 
      router.push({ path: '/login', query: { redirect: router.currentRoute.value.fullPath } })
      return 
    }
    await rateMovie(token, movieId.value, score)
    showRate.value = false
    await refreshRatings()
    myRating.value = Number(score) || 0
  } catch (e) {
    console.error('评分失败', e)
  }
}
// 重新拉取评分列表并区分我的评分和其他用户评分
async function refreshRatings() {
  try {
    const res = await getMovieRatings(movieId.value, 100)
    const data = res.data || { average: 0, count: 0, items: [] }
    const items = Array.isArray(data.items) ? data.items : []
    // 取出当前用户评分（my_rating/myRating/user_score/userScore），其余为其他用户
    const possible = data.my_rating ?? data.myRating ?? data.user_score ?? data.userScore
    myRating.value = Number.isFinite(Number(possible)) && Number(possible) > 0 ? Number(possible) : null
    // 后端已排除当前用户评分，这里仅随机抽取 10 条展示
    ratings.value = { items: pickRandom(items, 10) }
    avg.value = { average: Number.isFinite(Number(data.average)) ? Number(data.average) : 0, count: Number(data.count || 0) }
  } catch {
    ratings.value = { items: [] }
    avg.value = { average: 0, count: 0 }
  }
}

onMounted(load)
watch(() => route.params.id, () => { load(); syncAdded() })

function syncAdded() {
  try {
    const id = detail.value?.id ?? detail.value?.movieId ?? movieId.value
    inWatchlist.value = id != null ? watchlistService.has(id) : false
  } catch { inWatchlist.value = false }
}

// 初始同步
watch(detail, () => syncAdded())
onMounted(() => {
  syncAdded()
  if (typeof window !== 'undefined') window.addEventListener('storage', onStorage)
})
function onStorage(e){
  try {
    const key = e?.key || ''
    if (typeof key === 'string' && key.startsWith('watchlist_v1_')) syncAdded()
  } catch (err) { void 0 }
}
onBeforeUnmount(() => { if (typeof window !== 'undefined') window.removeEventListener('storage', onStorage) })

// 计算第 n 颗星的填充百分比（支持半星/任意小数）
function starFillPercent(score, n) {
  const s = Math.max(0, Math.min(5, Number(score) || 0))
  const fill = Math.max(0, Math.min(1, s - (n - 1)))
  return `${Math.round(fill * 100)}%`
}
</script>

<style scoped>
.page { min-height: 100vh; color: #fff; position: relative; z-index: 1; }
.page-bg { position: fixed; inset: 0; background: #0f0f0f center/cover no-repeat; z-index: 0; }

/* 顶部返回行 */
.page-topbar { padding: 6px 16px 0; position: relative; z-index: 4; margin-top: -6px; }

/* 顶部横幅 */
.hero { position: relative; border-radius: 0; overflow: hidden; margin: -8px 0 0; min-height: 60vh; }
.hero-content { position: absolute; inset: 0; display: grid; grid-template-columns: 240px 1fr; gap: 20px; padding: 16px; align-items: start; padding-top: 2vh; z-index: 3; }
.poster { width: 240px; height: 340px; background: #222 center/cover no-repeat; border-radius: 10px; align-self: start; box-shadow: 0 10px 30px rgba(0,0,0,.6); }
.info { align-self: start; background: rgba(15,15,15,0.25); backdrop-filter: blur(1px); padding: 10px 12px; border-radius: 10px; }
.title-line { display:flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.title { margin: 0; font-size: 28px; font-weight: 800; letter-spacing: .2px; }
.year { color: #bdbdbd; font-size: 14px; }
.avg-chip { margin-left: auto; background: #1f1f1f; color: #ffd54f; border: 1px solid #3a3a3a; padding: 4px 8px; border-radius: 999px; font-size: 12px; }
.genres { display:flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.g-tag { background: #1f1f1f; color:#bdbdbd; padding: 4px 10px; border-radius: 999px; font-size: 12px; }
.meta-grid { margin: 8px 0 6px; display: grid; grid-template-columns: 140px 1fr; row-gap: 8px; column-gap: 14px; }
.meta-row.full { grid-column: 1 / -1; display: grid; grid-template-columns: auto 1fr; column-gap: 12px; }
.meta-row .label { color:#bdbdbd; font-size: 12px; background: #1a1a1a; border: 1px solid #262626; padding: 2px 8px; border-radius: 999px; display: inline-block; box-sizing: border-box; }
.meta-row .value { color:#eaeaea; font-size: 13px; word-break: break-word; overflow-wrap: anywhere; }
.link { color:#8ab4f8; text-decoration: none; }
.link:hover { text-decoration: underline; }
.overview { color: #d0d4d7; line-height: 1.7; margin: 0 0 12px; max-width: 110ch; }
@media (min-width: 1280px) {
  .overview { max-width: 120ch; }
}
.actions { display:flex; gap: 12px; }
.btn { background: rgba(255,255,255,0.12); color:#fff; border: 1px solid rgba(255,255,255,0.18); border-radius: 8px; padding: 8px 14px; font-size: 14px; cursor: pointer; transition: background .2s ease, transform .1s ease; }
.btn:hover { background: rgba(255,255,255,0.2); transform: translateY(-1px); }
.btn-primary { background: #ff4e4e; border-color: #ff4e4e; }
.btn-primary:hover { background: #ff3333; }

/* 我的评分星星（按钮内缩小版） */
.my-stars { display:inline-flex; gap: 2px; vertical-align: middle; }
.my-stars .star2 { width: 14px; height: 14px; }
.my-stars .star2-bg, .my-stars .star2-fill { font-size: 14px; line-height: 14px; }

/* 返回按钮样式（与播放页一致） */
.back-btn {
  background: #fff;
  color: #000;
  border: 1px solid #e5e5e5;
  border-radius: 10px;
  padding: 8px 14px;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  transition: background .15s ease, transform .1s ease;
  margin-left: 6px;
}
.back-btn:hover { background: #f2f2f2; transform: translateY(-1px); }
.back-btn:focus-visible { outline: 2px solid #000; outline-offset: 2px; }

/* 评分列表 */
.ratings-section { margin: -16px 8px 12px; background: rgba(18,18,18,0.6); border-radius: 10px; padding: 14px 16px; box-shadow: 0 6px 18px rgba(0,0,0,.35); position: relative; z-index: 2; min-height: 360px; }
.section-header { display:flex; align-items: baseline; gap: 12px; margin-bottom: 8px; }
.section-title { margin: 0; font-size: 18px; font-weight: 700; }
.section-meta { color:#bdbdbd; font-size: 13px; }
.rating-list { display:grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.rating-item { display:flex; gap: 10px; background: #181818; border-radius: 10px; padding: 12px; }
.avatar { width: 36px; height: 36px; border-radius: 50%; background: #262626; display:flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; }
.ri-right { flex: 1; min-width: 0; }
.ri-head { display:flex; align-items: center; gap: 10px; }
.name { font-weight: 600; }
.stars { display: inline-flex; gap: 3px; font-size: 16px; line-height: 1; }
.star2 { position: relative; display: inline-block; width: 16px; height: 16px; }
.star2-bg, .star2-fill { position: absolute; inset: 0; font-size: 16px; line-height: 16px; }
.star2-bg { color: #555; }
.star2-fill { color: #ffb300; overflow: hidden; white-space: nowrap; width: 0; }
.score { margin-left: auto; color: #ddd; font-weight: 600; }
.empty { color:#9aa0a6; text-align: center; padding: 20px 0; }

/* 响应式 */
@media (max-width: 900px) {
  .hero-content { grid-template-columns: 160px 1fr; padding-top: 1.5vh; }
  .poster { width: 160px; height: 220px; }
  .hero { min-height: 56vh; }
  .ratings-section { margin-top: -10px; min-height: 300px; background: rgba(18,18,18,0.58); }
  .rating-list { grid-template-columns: 1fr; }
}
@media (min-width: 1280px) {
  .title { font-size: 32px; }
  .title-line { gap: 16px; margin-bottom: 12px; }
  .info { padding: 12px 16px; }
  .meta-grid { grid-template-columns: 160px 1fr; column-gap: 16px; row-gap: 10px; }
  .meta-row.full { grid-template-columns: auto 1fr; }
}
@media (max-width: 640px) {
  .hero { min-height: 60vh; }
  .hero-content { grid-template-columns: 1fr; padding-top: 1.5vh; }
  .poster { order: 2; justify-self: start; }
  .info { order: 1; }
  .ratings-section { margin-top: -6px; min-height: 260px; background: rgba(18,18,18,0.56); }
  .rating-list { grid-template-columns: 1fr; }
}
</style>